const { tagMap, globalAttrMap, eventMap, metaViewportContentMap, relMap } = require('./zhtmdata');
const { vonModifiersMap, vbindModifiersMap } = require('./zvuedata');
const zcss = require('./zcss');
const zjs = require('./zjs');
const zcssdata = require('./zcssdata');
const transformVue = require('./transformVue');
const prettier = require("prettier");

var vonRE = /(^@|^v-事件:|^v-on:)(.+)/;
var vbindRE = /(^:|^\.|^v-绑定:|^v-bind:)(.+)/;
var vslotRE = /(^v-插槽(:|$)|^#)(.+)/;
var vforInRE = /([\s\S]*?)\s+(于)\s+([\s\S]*)/;
var vforOfRE = /([\s\S]*?)\s+(自)\s+([\s\S]*)/;
// var vforIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;

function attrHandler(node, attr, eAttr) {
    if (typeof eAttr === 'string') {
        node.attrs[eAttr] = node.attrs[attr];
    } else {
        node.attrs[eAttr['eName']] = eAttr['attrValues'][node.attrs[attr]] || node.attrs[attr];
    }
    delete node.attrs[attr]; // 不删除中文属性, 以便 CSS 属性选择器使用;
}

function vueDirectivesHandler(zTag, nodeAttrs, attr) {
    if (vonRE.test(attr)) {
        let prefix, evStr;
        let changed = false;
        let matchResult = attr.match(vonRE);
        prefix = matchResult[1];
        if (prefix === 'v-事件:') {
            prefix = 'v-on:';
            changed = true;
        }
        evStr = matchResult[2];

        if (evStr.match(/[\u4e00-\u9fa5]/)) {
            if (evStr.includes('.')) {
                let ev, modifier;
                [ev, ...modifier] = evStr.split('.'); // 修饰符可以串联, 例如: 点击.阻止.禁止
                let eventNameWithOn = ev + '时';
                if (eventNameWithOn in eventMap) {
                    ev = eventMap[eventNameWithOn].slice(2);
                    changed = true;
                }
                if (modifier.length === 1) {
                    if (modifier in vonModifiersMap) {
                        modifier = vonModifiersMap[modifier];
                        changed = true;
                    }
                } else {
                    let mod, newMods=[];
                    for (mod of modifier) {
                        if (mod in vonModifiersMap) {
                            mod = vonModifiersMap[mod];
                            changed = true;
                        }
                        newMods.push(mod);
                    }
                    modifier = newMods.join('.');
                }
                evStr = ev + '.' + modifier;
            } else {
                if ((evStr + '时') in eventMap) {
                    evStr = eventMap[evStr + '时'].slice(2);
                    changed = true;
                }
            }    
        }

        if (changed) {
            nodeAttrs[prefix + evStr] = nodeAttrs[attr];
            delete nodeAttrs[attr];
        }
        
        return true;
    }

    if (vbindRE.test(attr)) {
        let prefix, propStr;
        let changed = false;
        let matchResult = attr.match(vbindRE);
        prefix = matchResult[1];
        if (prefix === 'v-绑定:') {
            prefix = 'v-bind:';
            changed = true;
        }
        propStr = matchResult[2];

        if (propStr.match(/[\u4e00-\u9fa5]/)) {
            if (propStr.includes('.')) {
                let prop, modifier;
                [prop, modifier] = propStr.split('.');
                if (tagMap[zTag] && tagMap[zTag]['attrs'] && prop in tagMap[zTag]['attrs']) {
                    let eprop = tagMap[zTag]['attrs'][prop];
                    if (typeof eprop === 'string') {
                        prop = eprop;
                    } else {
                        prop = eprop['eName'];
                    }
                    changed = true;
                } else
                    if (prop in globalAttrMap) {
                        let eprop = globalAttrMap[prop];
                        if (typeof eprop === 'string') {
                            prop = eprop;
                        } else {
                            prop = eprop['eName'];
                        }
                        changed = true;
                    }
                // if (prop in globalAttrMap) {
                //     prop = globalAttrMap[prop];
                //     changed = true;
                // }
                if (modifier in vbindModifiersMap) {
                    modifier = vbindModifiersMap[modifier];
                    changed = true;
                }
                propStr = prop + '.' + modifier;
            } else {
                if (tagMap[zTag] && tagMap[zTag]['attrs'] && propStr in tagMap[zTag]['attrs']) {
                    let eprop = tagMap[zTag]['attrs'][propStr];
                    if (typeof eprop === 'string') {
                        propStr = eprop;
                    } else {
                        propStr = eprop['eName'];
                    }
                    changed = true;
                } else
                    if (propStr in globalAttrMap) {
                        let eprop = globalAttrMap[propStr];
                        if (typeof eprop === 'string') {
                            propStr = eprop;
                        } else {
                            propStr = eprop['eName'];
                        }
                        changed = true;
                    }
                // if (propStr in globalAttrMap) {
                //     propStr = globalAttrMap[propStr];
                //     changed = true;
                // }
            }    
        }

        if (changed) {
            nodeAttrs[prefix + propStr] = nodeAttrs[attr];
            delete nodeAttrs[attr];
        }
        
        return true;
    }

    if (attr === 'v-取') {
        let value = nodeAttrs[attr];
        let matchResult = value.match(vforInRE) || value.match(vforOfRE);
        if (matchResult) {
            value = matchResult[1] + (matchResult[2] === '于' ? ' in ': ' of ') + matchResult[3];
            nodeAttrs['v-for'] = value;
            delete nodeAttrs[attr];
        }
        return true;
    }
    
    if (vslotRE.test(attr)) {
        let matchResult = attr.match(vslotRE);
        let prefix = matchResult[1].replace(/v-插槽/, 'v-slot');
        let slotName = matchResult[3].replace(/默认/, 'default');
        if (prefix+slotName !== attr) {
            nodeAttrs[prefix+slotName] = nodeAttrs[attr];
            delete nodeAttrs[attr];
        }
        return true;
    }

    return false;
}

function matchTag(tree, zTag) {
    tree.match({ tag: zTag }, node => {
        if (typeof tagMap[zTag] === 'string') {
            node.tag = tagMap[zTag];
        } else {
            node.tag = tagMap[zTag]['eName'];
        }

        if (node.attrs) {
            for (let attr in node.attrs) {
                if (attr.startsWith('数据-')) {
                    let eAttr = 'data-' + attr.slice(3);
                    node.attrs[eAttr] = node.attrs[attr];
                    delete node.attrs[attr]; // 不删除中文属性, 以便 CSS 属性选择器使用?
                    continue
                }
                
                if (vueDirectivesHandler(zTag, node.attrs, attr)) {
                    continue
                }

                if (attr === '样式') { // 处理内联样式
                    node.attrs['style'] = zcss.transpile("{" + node.attrs[attr] + "}").slice(1, -1);
                    delete node.attrs['样式'];
                    continue 
                }

                if (attr === '媒体') { // 多个标签有 '媒体' 属性
                    let zValue = node.attrs['媒体'];
                    let mediaQueryMap = zcssdata.mediaQueryMap;
                    let eValue = zValue.replace(/[\u4e00-\u9fa5-]+/g, function(word) {
                        return mediaQueryMap[word] || word;
                    });
                    node.attrs['media'] = eValue;
                    delete node.attrs['媒体'];
                    continue
                }

                if (tagMap[zTag]['attrs'] && attr in tagMap[zTag]['attrs']) {
                    let eAttr = tagMap[zTag]['attrs'][attr];
                    attrHandler(node, attr, eAttr);
                } else
                    if (attr in globalAttrMap) {
                        let eAttr = globalAttrMap[attr];
                        attrHandler(node, attr, eAttr);
                    } else
                        if (attr in eventMap) {
                            let eAttr = eventMap[attr];
                            node.attrs[eAttr] = zjs.transpile(node.attrs[attr]).trimEnd();
                            delete node.attrs[attr]; // 不删除中文属性, 以便 CSS 属性选择器使用;
                        }
            }
        }
        // console.log(node);
        return node;
    });
}

function test(options) {
    return function (tree) {
        for (let key in tagMap) {
            if (key === '样式') {
                样式翻译();
            }/*  else 
            if (key === '脚本') {
                脚本翻译();
            } */ else {
                matchTag(tree, key);
            }
        }
        
        function 样式翻译() {tree.match({ tag: '样式' }, node => {
            node.tag = 'style';
            node.content = zcss.transpile(node.content);
            let styleAttrMap = tagMap.样式.attrs
            if (node.attrs) {
                /* let styleAttrMap = {
                    类型: 'type',
                    媒体: 'media',
                    使用一次: 'nonce',
                    标题: 'title',
                    // ...globalAttrMap
                } */
                for (let attr in node.attrs) {
                    let eAttr = styleAttrMap[attr];
                    if (eAttr) {
                        if (eAttr === 'media') { // 媒体查询
                            let zValue = node.attrs['媒体'];
                            let mediaQueryMap = zcssdata.mediaQueryMap;
                            let eValue = zValue.replace(/[\u4e00-\u9fa5-]+/g, function(word) {
                                return mediaQueryMap[word] || word;
                            });
                            node.attrs['media'] = eValue;
                            delete node.attrs['媒体'];
                        } else {
                            node.attrs[eAttr] = node.attrs[attr];
                            delete node.attrs[attr];
                        }
                    }
                }
            }
            return node;
        });}
        
        function 脚本翻译() {tree.match({ tag: '脚本' }, node => {
            node.tag = 'script';
            console.log(node.content);
            // try {
            //     console.log(render([node], options));
            // } catch (error) {
            //     console.log(error);
            // }
            
            // node.content = '\n' + zjs.transpile(node.content);
            // node.content = '\n' + prettier.format(zjs.transpile(node.content), { parser: "typescript" });
            let scriptAttrMap = tagMap.脚本.attrs
            if (node.attrs) {
                for (let attr in node.attrs) {
                    let eAttr = scriptAttrMap[attr];
                    attrHandler(node, attr, eAttr);
                }
            }
            return node;
        });}
    }
}

function secondPass(options) {
    // HTML 中不需要使用 '中翻英_xxx' 函数, 中文会被自然地正确处理.
    return function (tree) {
        tree.match({ tag: 'script' }, node => { // 必须二次处理, 否则脚本中形如 '<p>hello world</p>' 会变成 ',[object object],'
            if (node.content === undefined) {return node;}
            node.content = zjs.transpile(node.content);
            node.content = transformVue.transVue(node.content);
            return node;
        });

        function 视口内容处理(内容) {
            let k, v;
            [k, v] = 内容.split('=');
            k = k.trim();
            v = v.trim();
            return metaViewportContentMap.keys[k] + '=' + metaViewportContentMap.vals[v];
        }

        tree.match({ tag: 'meta' }, node => {
            if (('name' in node.attrs) && node.attrs['name'] === 'viewport'
                 && ('content' in node.attrs) && node.attrs['content'].match(/[\u4e00-\u9fa5]/)) {
                let 内容 = node.attrs['content'];
                if (内容.match(/\,/)) {
                    let 分项列表 = 内容.split(',');
                    let 新列表 = [];
                    for (let 分项 of 分项列表) {
                        分项 = 视口内容处理(分项);
                        新列表.push(分项);
                    }
                    内容 = 新列表.join(', ');
                } else {
                    内容 = 视口内容处理(内容);
                }
                node.attrs['content'] = 内容;
            }
            return node;
        });

        tree.match({ tag: 'link' }, node => {
            if (('rel' in node.attrs) && node.attrs['rel'].match(/[\u4e00-\u9fa5]/)) {
                let 关系列表 = node.attrs['rel'].split(' ');
                let 新关系列表 = [];
                for (let 元素 of 关系列表) {
                    元素 = relMap.attrValues[元素] || 元素;
                    新关系列表.push(元素);
                }
                let 新关系 = 新关系列表.join(' ');
                node.attrs['rel'] = 新关系;
            }
            return node;
        });

        tree.match({ tag: /z-(.+)/ }, node => { // 处理 vue 中自定义的标签
            // console.log(node.tag);
            if (node.attrs) {
                for (let attr in node.attrs) {
                    // console.log(attr);
                    if (vueDirectivesHandler(node.tag, node.attrs, attr)) {
                        continue
                    }

                    if (attr.match(/[\u4e00-\u9fa5]/)) {
                        if (attr in globalAttrMap) {
                            let eAttr = globalAttrMap[attr];
                            attrHandler(node, attr, eAttr);
                        } else
                            if (attr in eventMap) {
                                let eAttr = eventMap[attr];
                                node.attrs[eAttr] = zjs.transpile(node.attrs[attr]).trimEnd();
                                delete node.attrs[attr]; // 不删除中文属性, 以便 CSS 属性选择器使用;
                            }
                    }
                }
            }
            return node;
        });
    }
}

module.exports = {
    test,
    secondPass
}